/*
 * @Author: zhanwei xu
 * @Date: 2023-08-19 17:30:45
 * @LastEditors: zhanwei xu
 * @LastEditTime: 2024-02-04 21:52:30
 * @Description: 
 * 
 * Copyright (c) 2024 by zhanwei xu, Tsinghua University, All Rights Reserved. 
 */
import { appRef } from "@/models/app.ref";
import { BaseServices } from "./base.services";
import { RoleEnum } from "@/models/@types";
import { ChatWorkModelInfo } from "@/models/chat-work";
import { AssetInfo } from "@/models/asset";
import { Console } from "console";

export type MessageInfo = {
  role: RoleEnum;
  content: string;
  assets?: AssetInfo[];
};

export class WorkService extends BaseServices {
  private static _ins: WorkService = new WorkService();
  public static get ins(): WorkService {
    return this._ins ? this._ins : (this._ins = new WorkService());
  }

  /** 获取模型列表 */
  public getModelList(): Promise<void> {
    const url = "https://jump.zaiwen.top/admin/get_mode/";
    return new Promise<void>((resolve) => {
      if (appRef.chatWork.models?.length) {
        resolve();
      } else {
        this.get(url).then((res: ChatWorkModelInfo[]) => {
          appRef.chatWork.setModels(res);
          resolve();
        });
      }
    });
  }

  public async sendStream(key: string, question: string, assets: AssetInfo[] = [], continuous: boolean = false, chunk: (data: string) => void, callback: () => void, quote: string = undefined): Promise<void> {
    if (!quote && question) quote = await appRef.chatWork.addMenuAnswer(RoleEnum.User, question, "", assets);
    const currMenu = appRef.chatWork.currMenu;
    let model = appRef.chatWork.getModel(currMenu?.modeluid);
    if (!model?.url) return;
    const url = model.url;
    let message: any = currMenu?.sessions
      ?.filter((val) => val.role !== RoleEnum.Tip)
      ?.map(({ role, richtext, assets }) => {
        const item: any = { role, content: richtext };
        if (model.vision && assets?.length) {
          assets[0]?.format?.includes('image') ? item.assets = assets?.map((val) => val.id) : item.fileid = assets[0].id
        }
        return item;
      });
    if (!continuous) {
      message = message.slice(-5);
    }
    if (currMenu?.prompt) {
      const prompt = await appRef.prompt.get(currMenu?.prompt);
      const item = { role: RoleEnum.System, content: prompt?.value };
      console.log(prompt);
      if (prompt?.continuous || continuous) {
        message.unshift(item);
      } else {
        message.splice(message.length - 1, 0, item);
      }
    }
    const data = {
      message,
      mode: model.value,
      key: appRef.user.data.openai_key,
    };
    return this.stream(
      key,
      url,
      data,
      chunk,
      (data: string) => {
        callback();
        if (data) appRef.chatWork.addMenuAnswer(RoleEnum.AI, data.toString(), quote);
      },
      (err) => {
        appRef.chatWork.addMenuAnswer(RoleEnum.Tip, err.toString());
      }
    );
  }

  /**
   * 优化、扩写 短句
   * @param key 
   * @param message 
   * @param chunk 
   * @param callback 
   * @returns 
   */
  public async optimize(key: string, message: string, chunk: (data: string) => void, callback: () => void): Promise<void> {
    const url = 'https://www.13042332817.top/improve_prompt';
    const data = { message };
    return this.stream(key, url, data, chunk, callback)
  }

  /** 停止请求 **/
  public stopSend(key: string, callback: () => void): void {
    this.stopStream(key);
    callback();
  }
}

export const workService: WorkService = WorkService.ins;
